package config

import (
	"encoding/json"
	"fmt"
	"io/ioutil"
	"path/filepath"
	"strings"
	"sync"

	"github.com/tujiaw/goutil"
)

type JsonInfo struct {
	ExtName []struct {
		Name string   `json:"name"`
		Icon string   `json:"icon"`
		Ext  []string `json:"ext"`
	} `json:"extname"`

	Preview struct {
		Enable bool     `json:"enable"`
		Limit  int64    `json:"limit"`
		List   []string `json:"list"`
	} `json:"preview"`

	Address  string `json:"address"`
	Username string `json:"username"`
	Password string `json:"password"`
}

type PairString struct {
	First  string
	Second string
}

type Info struct {
	exts          map[string]PairString
	previewEnable bool
	previewLimit  int64
	previewList   []string
	address       string
	username      string
	password      string
}

var instance *Info
var once sync.Once

func Instance() *Info {
	once.Do(func() {
		instance = &Info{}
		instance.exts = make(map[string]PairString)
	})
	return instance
}

func (info *Info) Init(pathstr string) error {
	b, err := ioutil.ReadFile(pathstr)
	if err != nil {
		return err
	}

	var jsonInfo JsonInfo
	err = json.Unmarshal(b, &jsonInfo)
	if err != nil {
		return err
	}

	for _, item := range jsonInfo.ExtName {
		for _, v := range item.Ext {
			if _, ok := info.exts[v]; ok {
				fmt.Printf("ext name exist, name:%s\n", v)
			} else {
				info.exts[v] = PairString{item.Name, item.Icon}
			}
		}
	}

	info.previewEnable = jsonInfo.Preview.Enable
	info.previewLimit = jsonInfo.Preview.Limit
	info.previewList = jsonInfo.Preview.List
	info.address = jsonInfo.Address
	info.username = jsonInfo.Username
	info.password = jsonInfo.Password
	return nil
}

func (info *Info) Ext(ext string) PairString {
	if a, ok := info.exts[strings.ToLower(ext)]; ok {
		return a
	}
	return PairString{"文件", "fa-file-o"}
}

func (info *Info) GetNameAndIcon(pathstr string) (string, string) {
	result := PairString{}
	if goutil.IsDir(pathstr) {
		result.First = "目录"
		result.Second = "fa-folder"
	} else {
		result = info.Ext(filepath.Ext(pathstr))
	}
	return result.First, result.Second
}

func (info *Info) EnablePreview(ext string, bsize int64) bool {
	if !info.previewEnable {
		return false
	}

	if bsize < info.previewLimit {
		ext = strings.ToLower(ext)
		if i := goutil.StringsIndexOf(info.previewList, ext); i >= 0 {
			return true
		}
	}
	return false
}

func (info *Info) PreviewUrl(ext string, bsize int64, url string) string {
	if info.EnablePreview(ext, bsize) {
		return fmt.Sprintf("http://ow365.cn/?i=23123&furl=http://f.ningto.com%s", url)
	}
	return ""
}

func (info *Info) Address() string {
	return info.address
}

func (info *Info) Username() string {
	return info.username
}

func (info *Info) Password() string {
	return info.password
}
